package com.bt.lms.ui.page.sys.user.action;

import com.bt.lms.constants.SysBizTypeConstant;
import com.bt.lms.entity.Role;
import com.bt.lms.entity.User;
import com.bt.lms.entity.page.Page;
import com.bt.lms.network.msg.RespMsg;
import com.bt.lms.ui.page.sys.utils.NetWorkUtils;
import com.bt.lms.ui.vo.PageSkipInfo;
import com.bt.lms.network.msg.ReqMsg;
import com.bt.lms.ui.page.sys.ServerInfo;
import com.bt.lms.ui.page.sys.user.PageAdd;
import com.bt.lms.ui.page.sys.utils.Encode;
import com.bt.lms.ui.page.sys.utils.ArrayUtils;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 保存按钮事件（添加用户界面
 *
 * @author 徐大永
 */
public class UASaveBtnAction implements EventHandler<ActionEvent> {

    /**
     * 界面跳转数据
     */
    private final PageSkipInfo pageSkipInfo;

    /**
     * 角色合集
     */
    private final List<Role> roles;

    /**
     * 构建事件
     *
     * @param pageSkipInfo 界面跳转数据
     * @param roles 角色合集
     */
    public UASaveBtnAction(PageSkipInfo pageSkipInfo, List<Role> roles) {
        this.pageSkipInfo = pageSkipInfo;
        this.roles = roles;
    }

    /**
     * 事件实现
     *
     * @param event the event which occurred
     */
    @Override
    public void handle(ActionEvent event) {

        //1.获取用户输入
        User user = getInPut();
        //2.验证用户输入
        String result = verifyInPut(user);
        //3.组装网络消息包
        if (null == result) {
            //验证通过
            //3.1发送请求
            //3.1.1 组装消息包
            ReqMsg reqMsg = Encode.encodeToMsg(user, SysBizTypeConstant.USER_ADD);
            byte[] bytes = reqMsg.toBytes();
            //3.1.2 组网
            Socket socket = pacNet();
            OutputStream out;
            try {
                out = socket.getOutputStream();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            //3.1.3 发网，返回结果
            boolean receive = sendReq(out, bytes);
            //判断是否发送成功
            if (receive) {
                try {
                    //3.2 接收响应
                    InputStream in = socket.getInputStream();
                    //3.2.1 接受响应
                    List<byte[]> bufS = NetWorkUtils.receive(in);
                    //3.2.2 处理结果
                    byte[] respBytes = ArrayUtils.joinBytes(bufS);
                    //3.2.3 转消息
                    RespMsg respMsg = RespMsg.toRespMsg(respBytes);
                    //3.2.4 比较状态
                    short status = respMsg.getStatus();
                    if (status == RespMsg.NETWORK_STATUS_NORMAL) {
                        //资源关闭
                        in.close();
                        out.close();
                        socket.close();
                        //成功发送，程序结束
                        finish();
                    } else {
                        String failStr = "未能保存成功，请稍候重试。";
                        hintFrame(failStr);//提示框
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            } else {
                hintFrame("网络异常，请检查网络或联系客服。");//提示框
            }
        } else {
            hintFrame(result);//提示框
        }
    }

    /**
     * 程序结束
     */
    private void finish() {

        //提示弹窗
        Alert alert = new Alert(Alert.AlertType.INFORMATION);

        //保存提示
        alert.setTitle("保存");
        alert.setHeaderText(null);
        alert.setContentText("保存成功");
        alert.showAndWait();

        //界面跳转
        NetWorkUtils.reqUserPagingPage(pageSkipInfo,new Page<>());
    }

    /**
     * 发送请求
     * 包含接收响应
     *
     * @param out 输出流
     * @param bytes  要发送的数据
     * @return 发送结果
     */
    private boolean sendReq(OutputStream out, byte[] bytes) {


        try {
            out.write(bytes);
            out.flush();
        } catch (IOException e) {
            return false;
        }

            return true;

    }

    /**
     * 组网
     *
     * @return 网
     */
    private Socket pacNet() {

        String ip = ServerInfo.IP;
        int port = ServerInfo.PORT;

        Socket socket;
        try {
            socket = new Socket(ip, port);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return socket;
    }

    /**
     * 验证用户输入
     *
     * @return 验证情况
     */
    private String verifyInPut(User user) {
        String hint = "";

        //1.验证邮箱  必填 文本 64位以下邮箱
        String emailStr = user.getAccountNumber();
        if ("".equals(emailStr)) {
            //没有填写邮箱
            hint += "邮箱不可为空，请重新输入。\t\n";
        } else {
            //验证邮箱格式
            Pattern pattern = Pattern.compile("\\w+@(\\w+.)+[a-z]{2,3}");//\w表示a-z，A-Z，0-9(\\转义符)
            Matcher matcher = pattern.matcher(emailStr);
            boolean matches = matcher.matches();
            if (!matches) {
                //邮箱格式不正确
                hint += "邮箱格式不正确，请重新输入。\t\n";
            } else {
                int length = emailStr.length();
                if (length > 64) {
                    //长度大于64
                    hint += "邮箱过长，请重新输入\t\n";
                }
            }
        }

        //2.验证用户名   必填 文本 小
        String nameStr = user.getName();
        if ("".equals(nameStr)) {
            //没有姓名
            hint += "姓名不可空，请重新输入。\t\n";
        } else {
            //姓名过长
            int length = nameStr.length();
            if (length > 32) {
                hint += "姓名过长，请重新输入\t\n";
            }
        }

        //3.证件号码
        Integer idTypeStr = user.getCodeType();//证件类型
        String id = user.getCode();//证件号码
        String s = idVerify(idTypeStr, id);
        hint += s;

        //4.所属单位  必填 文本 小
        String unitStr = user.getUnit();
        if ("".equals(unitStr)) {
            //没有单位信息
            hint += "所属单位为空，请重新输入。\t\n";
        } else {
            //单位过长
            int length = unitStr.length();
            if (length > 32) {
                hint += "所属单位过长，请重新输入\t\n";
            }
        }

        //5.移动电话
        String mobilePhone = user.getMobilePhone();
        if ("".equals(mobilePhone)) {
            //没有电话
            hint += "移动电话为空，请重新输入。\t\n";
        } else {

            //纯数字
            try {
                //是否是数字
                Long.valueOf(mobilePhone);
                //电话过长
                int length = mobilePhone.length();
                if (length > 32) {
                    hint += "电话过长，请重新输入\t\n";
                }
            } catch (NumberFormatException e) {
                hint += "电话需要是纯数字，请重新输入\t\n";
            }
        }

        if ("".equals(hint)) {
            return null;
        } else {
            return hint;
        }
    }

    /**
     * 获取用户输入
     *
     * @return 用户输入对象
     */
    private User getInPut() {
        User user = new User();

        //用户输入容器
        Pane pane = pageSkipInfo.getPane();
        //获取内容
        //邮箱
        TextField emailTF = (TextField) pane.lookup("#" + PageAdd.EMAIL_TF);
        String emailStr = emailTF.getText().trim();
        user.setAccountNumber(emailStr);
        //用户名
        TextField nameTF = (TextField) pane.lookup("#" + PageAdd.NAME_TF);
        String nameStr = nameTF.getText().trim();
        user.setName(nameStr);
        //证件类型
        ChoiceBox idTypeCB = (ChoiceBox) pane.lookup("#" + PageAdd.ID_TYPE_CB);
        String idTypeStr = (String) idTypeCB.getValue();
        int idType = -1;
        switch (idTypeStr) {
            case "身份证":
                idType = 1;
                break;
            case "士官证":
                idType = 2;
                break;
            case "学生证":
                idType = 3;
                break;
            case "驾驶证":
                idType = 4;
                break;
            case "护照":
                idType = 5;
                break;
            case "港澳通行证":
                idType = 6;
                break;
        }
        user.setCodeType(idType);
        //证件号码
        TextField idTF = (TextField) pane.lookup("#" + PageAdd.ID_TF);
        String idStr = idTF.getText().trim();
        user.setCode(idStr);
        //所属单位
        TextField unitTF = (TextField) pane.lookup("#" + PageAdd.UNIT_TF);
        String unitStr = unitTF.getText().trim();
        user.setUnit(unitStr);
        //移动电话
        TextField phoneTF = (TextField) pane.lookup("#" + PageAdd.PHONE_TF);
        String phoneStr = phoneTF.getText().trim();
        user.setMobilePhone(phoneStr);
        //关联角色
        user.setRoles(roles);

        return user;
    }

    /**
     * 证件号码验证
     *
     * @param idTypeStr 证件类型
     * @param id        证件号码
     */
    private String idVerify(Integer idTypeStr, String id) {
        //提示文本
        String hint = "";
        if (idTypeStr == 1) {
            //身份证 17数字，1数字或字母x  id  17位数字，最后一位数字或字母 总长18
            int idLen = id.length();
            if (idLen != 18) {
                //不等于18
                hint += "长度不对，请输入正确的身份证号码。\t\n";
            } else {
                try {
                    String substring = id.substring(0, 17);
                    Long.parseLong(substring);
                    char c = id.charAt(17);
                    if (!(c >= '0' && c <= '9')) {
                        if (c != 'X') {
                            hint += "格式错误，请输入正确的身份证号码（如有英文，请大写）。\t\n";
                        }
                    }
                } catch (NumberFormatException e) {
                    hint += "格式错误，请输入正确的身份证号码（如有英文，请大写）。\t\n";
                }
            }
        } else if (idTypeStr == 2) {
            //士官证  沈字第0100000号   第一位汉字，后续固定：字第*******号
            //总长11位
            int idLen = id.length();
            if (idLen != 11) {
                //长度不是11位
                hint += "长度错误，请输入正确的士官证号码。\t\n";
            } else {
                //汉字正则表达式
                String reg = "[\\u4e00-\\u9fa5]";
                //前三位
                char c = id.charAt(0);
                boolean start = String.valueOf(c).matches(reg);//开头是否是汉字
                boolean centre = id.startsWith("字第", 1); //二三位是否是字第
                //中间七位数字
                String number = id.substring(3, 10);
                //最后一位汉字
                boolean finish = id.endsWith("号");

                if (!start) {
                    //不是汉字开头
                    hint += "格式错误，请输入正确的士官证号码。\t\n";
                } else if (!centre) {
                    //二三位不是”字第“
                    hint += "格式错误，请输入正确的士官证号码。\t\n";
                } else if (!finish) {
                    //结尾不是“”
                    try {
                        Integer.parseInt(number);
                    } catch (NumberFormatException e) {
                        //中间7位不是数字
                        hint += "格式错误，请输入正确的士官证号码。\t\n";
                    }
                }
            }

        } else if (idTypeStr == 3) {
            //学生证
            //暂时无法判断，每个学校的学生证格式不一致
            //判断是否全为数字
            try {
                Long.parseLong(id);
            } catch (NumberFormatException e) {
                hint += "格式错误，请输入正确的学生证号码。\t\n";
            }
        } else if (idTypeStr == 4) {
            //驾驶证  12位 前两位省  后两位市  纯数字
            int idLen = id.length();
            if (idLen != 12) {
                hint += "长度错误，请输入正确的驾驶证号码。\t\n";
            } else {
                try {
                    Long.parseLong(id);
                } catch (NumberFormatException e) {
                    hint += "格式错误，请输入正确的驾驶证号码。\t\n";
                }
            }
        } else if (idTypeStr == 5) {
            //护照 长度9位
            int idLen = id.length();
            if (idLen != 9) {
                hint += "格式错误，请输入正确的护照号码。\t\n";
            }
        } else if (idTypeStr == 6) {
            //港澳通行证 9位 第一位C 后8位数字
            int idLen = id.length();
            if (idLen != 9) {
                hint += "长度错误，请输入正确的港澳通行证号码。\t\n";
            } else {
                boolean c = id.startsWith("C");
                if (!c) {
                    hint += "格式错误，请输入正确的港澳通行证号码。\t\n";
                } else {
                    String substring = id.substring(1);
                    try {
                        Long.parseLong(substring);
                    } catch (NumberFormatException e) {
                        hint += "格式错误，请输入正确的港澳通行证号码。\t\n";
                    }
                }
            }
        }
        return hint;
    }

    /**
     * 程序终止
     * 弹窗提示
     *
     * @param result 终止提示
     */
    private void hintFrame(String result) {
        //提示弹窗
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        //错误提示
        alert.setTitle("失败");
        alert.setHeaderText(null);
        alert.setContentText(result);
        alert.showAndWait();
    }

}
